package maze;

import java.util.ArrayList;

import test.Main;
import artifacts.*;

/**
 * @author Denis Toikka
 *
 */
public class Room {
	
	/**
	 * Room name.
	 */
	public String name;
	/**
	 * List of artifacts in the room.
	 */
	public ArrayList<Artifact> items = new ArrayList<Artifact>();
	/**
	 * Neighboring rooms. Wall by default.
	 */
	Room north = Maze.wall;
	Room east = Maze.wall;
	Room west = Maze.wall;
	Room south = Maze.wall;
	/**
	 * Is current room exit.
	 */
	public boolean isExit = false;
	/**
	 * Is current room portal.
	 */
	public boolean isPortal = false;
	/**
	 * Portal destination, if this room is a portal.
	 */
	public Room portalTo = null;
	
	/**
	 * @return
	 * Returns name of the room.
	 */
	public String getName() {
		if(this == Maze.wall) return "doesn't exist";
		else if(this == Maze.out) return "out of maze";
		else return this.name;
	}
	
	/**
	 * @param r
	 * Sets room north destination.
	 */
	void setNorth(Room r) {
		if(this.north == Maze.wall) {
			this.north = r;
			r.setSouth(this);
		}
	}
	/**
	 * @param r
	 * Sets room south destination.
	 */
	void setSouth(Room r) {
		if(this.south == Maze.wall) {
			this.south = r;
			r.setNorth(this);
		}
	}	
	/**
	 * @param r
	 * Sets room west destination.
	 */
	void setWest(Room r) {
		if(this.west == Maze.wall) {
			this.west = r;
			r.setEast(this);
		}
	}
	/**
	 * @param r
	 * Sets room east destination.
	 */
	void setEast(Room r) {
		if(this.east == Maze.wall) {
			this.east = r;
			r.setWest(this);
		}
	}
	
	/**
	 * @param direction = string {"N", "E", "S", "W"}
	 * @return
	 * Returns neighboring room.
	 */
	public Room getDirection(String direction) {
		if("N".equalsIgnoreCase(direction)) return this.north;
		else if("E".equalsIgnoreCase(direction)) return this.east;
		else if("S".equalsIgnoreCase(direction)) return this.south;
		else if("W".equalsIgnoreCase(direction)) return this.west;
		else return Maze.wall;
	}
	
	/**
	 * @param roomName
	 * @return
	 * Creates new room. Creates door between this room and new room.
	 * Destination: north.
	 */
	public Room createNorth(String roomName) {
		if(this.north != Maze.wall) return this.north;
		else {
			Room room = new Room();
			room.name = roomName;
			this.setNorth(room);
			return room;
		}
	}
	
	/**
	 * @param roomName
	 * @return
	 * Creates new room. Creates door between this room and new room.
	 * Destination: east.
	 */
	public Room createEast(String roomName) {
		if(this.east != Maze.wall) return this.east;
		else {
			Room room = new Room();
			room.name = roomName;
			this.setEast(room);
			return room;
		}
	}
	
	/**
	 * @param roomName
	 * @return
	 * Creates new room. Creates door between this room and new room.
	 * Destination: south.
	 */
	public Room createSouth(String roomName) {
		if(this.south != Maze.wall) return this.south;
		else {
			Room room = new Room();
			room.name = roomName;
			this.setSouth(room);
			return room;
		}
	}
	
	/**
	 * @param roomName
	 * @return
	 * Creates new room. Creates door between this room and new room.
	 * Destination: west.
	 */
	public Room createWest(String roomName) {
		if(this.west != Maze.wall) return this.west;
		else {
			Room room = new Room();
			room.name = roomName;
			this.setWest(room);
			return room;
		}
	}
	
	/**
	 * @return
	 * Creates exit from the maze.
	 */
	public Room createExit() {
		this.isExit = true;
		return this;
	}
	
	/**
	 * @param isDouble
	 * @param pathList
	 * @return
	 * Creates portal using list of path.
	 */
	public Room createPortal(boolean isDouble, String[] pathList) {
		if(this.isPortal == true || this.getPath(pathList) == Maze.wall) return this;
		else {
			Room portalDestination = this.getPath(pathList);
			if(isDouble) {
				if(portalDestination.isPortal == true) return this;
				else {
					portalDestination.isPortal = true;
					portalDestination.portalTo = this;
				}
			}
			this.isPortal = true;
			this.portalTo = portalDestination;
			return this;
		}
	}
	
	
	/**
	 * @param isDouble
	 * @param portalDestination
	 * @return
	 * Creates portal using shortcut.
	 */
	public Room createPortal(boolean isDouble, Room portalDestination) {
		if(this.isPortal == true || portalDestination == Maze.wall) return this;
		else {
			if(isDouble) {
				if(portalDestination.isPortal == true) return this;
				else {
					portalDestination.isPortal = true;
					portalDestination.portalTo = this;
				}
			}
			this.isPortal = true;
			this.portalTo = portalDestination;
			return this;
		}
	}
	
	/**
	 * @param pathList
	 * @return
	 * Validates if this path exist. Allows portals.
	 */
	public boolean validatePath(String[] pathList) {
		Room room = this;
		for(int i = 0; i<pathList.length; i++) {
			if(room.getDirection(pathList[i]) == Maze.wall) return false;
			else if(room.getDirection(pathList[i]).isPortal == true) 
						room = room.getDirection(pathList[i]).portalTo;
			else room = room.getDirection(pathList[i]);
		}
		return true;
	}
	
	/**
	 * @param pathList
	 * @return
	 * Returns path final destination. Portals not allows.
	 */
	public Room getPath(String[] pathList) {
		Room room = this;
		for(int i = 0; i<pathList.length; i++) {
			if(room.getDirection(pathList[i]) == Maze.wall) return Maze.wall;
			else room = room.getDirection(pathList[i]);
		}
		return room;
	}
	
	/**
	 * @return
	 * Return directions that exists for this room.
	 */
	public String existDoor() {
		String directions = "";
		if(this.north != Maze.wall) directions += "north";
		if(this.east != Maze.wall) {
			if(directions == "") directions += "east";
			else directions += ", east";
		}
		if(this.south != Maze.wall) {
			if(directions == "") directions += "south";
			else directions += ", south";
		}
		if(this.west != Maze.wall) {
			if(directions == "") directions += "west";
			else directions += ", west";
		}
		if(directions == "") directions = "you are in deadlock";
		return directions + ".";
	}
}

